package cn.ichar.provide.service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author imaye
 * @date 2021/7/5
 */
public class Goods {
    private String goodsName;
    private Integer count = 0;
    private Integer full;
    //获得lock对象
    private Lock lock = new ReentrantLock();
    //获得生产者等待队列对象
    private final Condition productorCondition = lock.newCondition();
    //获得消费者等待队列对象
    private final Condition customerCondition = lock.newCondition();

    public static void main(String[] args) {
        Goods goods = new Goods(20);
        Productor productor = new Productor(goods);
        Customer customer = new Customer(goods);
        List<Thread> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Thread thread = new Thread(productor, "生产者" + i);
            list.add(thread);
        }
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(customer, "消费者" + i);
            list.add(thread);
        }
        for (Thread thread : list) {
            thread.start();
        }
    }

    public Goods(Integer full) {
        this.full = full;
    }

    public void setGoods(String goodsName) {
        try {

//使用锁实现同步，获取所得操作，当锁被其他线程占用时，当前线程将进入休眠
            lock.lock();
            while (this.count == this.full) {
                System.out.println("商品库存很多，快来购买哦");
                try {

//满足条件时，线程休眠并释放锁。当调用 signalAll()时。线程唤醒并重新获得锁
                    productorCondition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.goodsName = goodsName;
            this.count++;
            System.out.println(Thread.currentThread().getName() + "生产" + this.toString());

//唤醒因productorCondition.await()休眠的线程
            customerCondition.signalAll();
        } finally {
            lock.unlock();//解锁
        }
    }

    public void getGoods() {
        try {
            lock.lock();
            while (this.count == 0) {
                System.out.println("商品正在生产中，亲稍等哦");
                try {
                    customerCondition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.count--;
            System.out.println(Thread.currentThread().getName() + "消费" + this.toString());

            //这个时候已经生产完了，生产者唤醒消费者进行消费
            productorCondition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    @Override
    public String toString() {
        return "Goods{" +
                "goodsName='" + goodsName + '\'' +
                ", count=" + count +
                '}';
    }
}


class Productor implements Runnable {
    private Goods goods;

    public Productor(Goods goods) {
        this.goods = goods;
    }

    @Override
    public void run() {
        while (true) {
            this.goods.setGoods("mac");
        }
    }
}


class Customer implements Runnable {
    private Goods goods;

    public Customer(Goods goods) {
        this.goods = goods;
    }

    @Override
    public void run() {
        while (true) {
            this.goods.getGoods();
        }
    }
}
